(*****************************************************************************
 * Delphi Plug-in Framework (DPF)
 * Copyright (C) 2006-2007 Tao Yuan
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the
 * License at http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.                                                               }
 *
 * The Initial Developer of the Original Code is Tao Yuan. Portions created by
 * Tao Yuan are Copyright (C) Tao Yuan (taoy.cn att gmail dott com)
 * All rights reserved.
 *****************************************************************************)
 
unit RDPluginRegistry;

interface

uses
  Classes,
  Rcl,
  RDIdentity, RDVersion, RDPathResolver, RdIntfs;

type  
  IPluginElement = interface;

  IPluginDescriptor = interface;
  IPluginFragment = interface;

  ILibrary = interface;
  IPluginPrerequisite = interface;
  IRegistryChangeListener = interface;
  IPluginRegistry = interface;

  IExtension = interface;
  IExtensionPoint = interface;
  IParameter = interface;
  IParameterDefinition = interface;


  IPluginElement = interface(IDocumentable)
  ['{3588A3BB-20A9-4CD6-9878-19EF402C72F4}']
      (**
       * Returns plug-in descriptor, this element belongs to. This method
       * should never return <code>null</code>.
       * @return plug-in descriptor, this element belongs to
       *)
    function getDeclaringPluginDescriptor: IPluginDescriptor; stdcall;
      (**
       * Returns descriptor of plug-in fragment that contributes this element.
       * This method may return <code>null</code>, if element is contributed by
       * plug-in directly.
       * @return descriptor of plug-in fragment that contributes this element
       *)
    function getDeclaringPluginFragment: IPluginFragment; stdcall;
  end;

  (**
   * This interface abstracts plug-in attribute, a &lt;ID,VALUE&gt; pair. Plug-in
   * attributes are not involved into JPF runtime internal logic and intended
   * to be used by plug-in developers.
   * @version $Id: PluginAttribute.java,v 1.3 2005/03/07 10:27:57 ddimon Exp $
   *)
  IPluginAttribute = interface(IPluginElement)
  ['{FE1CA409-618F-415E-9B22-1CE63803AAF7}']
    (**
     * @return attribute value as it is specified in manifest
     *)
    function getValue: string; stdcall;

    (**
     * @return collection of all sub-attributes of this attribute
     *)
    function getSubAttributes: IIntfCollection; stdcall; overload;

    (**
     * @param id ID of sub-attribute to look for
     * @return sub-attribute with given ID
     *)
    function getSubAttribute(id: String): IPluginAttribute; stdcall;

    (**
     * @param id ID of sub-attribute to look for
     * @return collection of all sub-attributes with given ID
     *)
    function getSubAttributes(id: String): IIntfCollection; stdcall; overload;

    (**
     * @return attribute, of which this one is child or <code>null</code> if
     *         this is top level attribute
     *)
    function getSuperAttribute: IPluginAttribute; stdcall;
  end;



  ILibrary = interface(IPluginElement)
  ['{D5D58CFD-3B0D-4680-AC52-16E2676DBBFA}']
      (**
       * Returns plug-in descriptor, this element belongs to. This method
       * should never return <code>null</code>.
       * @return plug-in descriptor, this element belongs to
       *)
    function getDeclaringPluginDescriptor: IPluginDescriptor; stdcall;
      (**
       * Returns descriptor of plug-in fragment that contributes this element.
       * This method may return <code>null</code>, if element is contributed by
       * plug-in directly.
       * @return descriptor of plug-in fragment that contributes this element
       *)
    function getDeclaringPluginFragment: IPluginFragment; stdcall;
    (**
     * @return path to resource
     *)
    function getPath(): string; stdcall;
    
    (**
     * @return <code>true</code> if this is "code" library
     *)
    function isCodeLibrary(): Boolean; stdcall;
    
    (**
     * This method should return collection of {@link String} objects that
     * represent resource name prefixes or package name patterns that are
     * available to other plug-ins.
     * <br>
     * For code library, prefix is a package name, for resource library,
     * the same rules applied to relative resource path calculated against
     * library path (you can replace slash characters in path with dots).
     * <br>
     * Example prefixes are:<br>
     * <code>
     * "*", "package.name.*", "package.name.ClassName", "resource/path(*
     * </code>
     * @return collection of exported resource name patterns
     *)
    function getExports: IStrCollection; stdcall;

    (**
     * @return library version identifier as specified in manifest file or
     *         <code>null</code>
     *)
    function getVersion(): TVersion; stdcall;
  end;

  (**
   * Main interface to get access to all meta-information for particular
   * plug-in, described in plug-in manifest file.
   * @see <a href="{@docRoot}/../plugin_0_4.dtd">plug-in DTD for standard
   *      registry implementation</a>
   * @see org.java.plugin.PluginRegistry
   * @version $Id: PluginDescriptor.java,v 1.2 2005/03/07 10:27:57 ddimon Exp $
   *)
   
  //IPluginDescriptor = interface(IIdentity, IDocumentable)
  IPluginDescriptor = interface(IDocumentable)
  ['{E541BA42-28C0-46F5-A18E-1B0C5EA604B4}']
    (**
     * Returns combination of plug-in ID and version identifier that is unique
     * within whole set of registered plug-ins.
     * @return unique ID for this plug-in
     *)
    function getUniqueId: String; stdcall;

    (**
     * @return vendor as specified in manifest file or empty string
     *)
    function getVendor: String; stdcall;

    (**
     * @return plug-in version identifier as specified in manifest file
     *)
    function getVersion: TVersion; stdcall;

    (**
     * Returns collection of all top level attributes defined in manifest.
     * @return collection of {@link PluginAttribute} objects
     *)
    function getAttributes: IIntfCollection; stdcall; overload;

    (**
     * @param id ID of attribute to look for
     * @return attribute with given ID
     *)
    function getAttribute(id: String): IPluginAttribute; stdcall;

    (**
     * @param id ID of attribute to look for
     * @return collection of all attributes with given ID
     *)
    function getAttributes(id: String): IIntfCollection; stdcall; overload;
    function getExtension(id: string): IExtension; stdcall;
    function getExtensionPoint(id: string): IExtensionPoint; stdcall;
    (**
     * Returns collection of all extension points defined in manifest.
     * @return collection of {@link ExtensionPoint} objects
     *)
    function getExtensionPoints: IIntfCollection; stdcall;
    (**
     * Returns collection of all extensions defined in manifest.
     * @return collection of {@link Extension} objects
     *)
    function getExtensions: IIntfCollection; stdcall;
//    function getExtension(id: string): IExtension; stdcall;
//    function getExtensionPoint(id: string): IExtensionPoint; stdcall;

    (**
     * Returns collection of all prerequisites defined in manifest.
     * @return collection of {@link PluginPrerequisite} objects
     *)
    function getPrerequisites: IIntfCollection; stdcall;

    (**
     * @return plug-ins registry
     *)
    function getRegistry: IPluginRegistry; stdcall;

    (**
     * @return plug-in class name as specified in manifest file or
     *         <code>null</code>
     *)
    function getPluginClassName: String; stdcall;

    (**
     * Returns collection of plug-in fragments which contributes to this
     * plug-in. One plug-in fragment may contribute to several versions of the
     * same plug-in, according to it's manifest.
     * @return collection of {@link PluginFragment} objects
     *)
    function getFragments: IIntfCollection; stdcall;
    (**
     * Returns collection of all libraries defined in manifest.
     * @return collection of {@link Library} objects
     *)
    function getLibraries: IIntfCollection; stdcall;
    function getLibrary(id: string): ILibrary; stdcall;
    (**
     * @return location from which this plug-in was registered
     *)
    function getLocation: string; stdcall;
    (**
     * @return path from which this plug-in was registered
     *)
    function getPath: string; stdcall;
    function getPrerequisite(id: string): IPluginPrerequisite; stdcall;
  end;

  IPluginFragment = interface(IDocumentable)
  ['{F64D4677-3207-41B0-922E-1426555D4AAD}']
    (**
     * @return unique ID for this plug-in fragment
     *)
    function getUniqueId: String; stdcall;

    (**
     * @return vendor as specified in manifest file or empty string
     *)
    function getVendor: String; stdcall;

    (**
     * @return plug-in fragment version identifier as specified in manifest file
     *)
    function getVersion: TVersion; stdcall;

    (**
     * @return ID of plug-in to which this fragment may contribute
     *)
    function getPluginId: String; stdcall;

    (**
     * @return version identifier of plug-in to which this fragment may
     *         contribute or <code>null</code> if no version specified in
     *         manifest
     *)
    function getPluginVersion: TVersion; stdcall;

    (**
     * @return plug-ins registry
     *)
    function getRegistry: IPluginRegistry; stdcall;

    (**
     * Checks is this fragment may contribute to given plug-in.
     * @param descr plug-in descriptor
     * @return <code>true</code> if this fragment may contribute to given
     *         plug-in
     *)
    function matches(descr: IPluginDescriptor): Boolean; stdcall;

    (**
     * @return location from which this fragment was registered
     *)
    function getLocation: string; stdcall;
  end;

  IPluginPrerequisite = interface(IPluginElement)
  ['{F06ADF42-D84D-4ED8-8C10-37A3AE9D1F93}']

    (**
     * @return ID of plug-in, this plug-in depends on
     *)
    function getPluginId(): string; stdcall;
    
    (**
     * @return desired plug-in version identifier or <code>null</code>
     *         if not specified
     *)
    function getPluginVersion(): TVersion; stdcall;
    
    (**
     * @return <code>true</code> if this prerequisite is propagated
     *         on depending plug-ins
     *)
    function isExported(): boolean; stdcall;

    (**
     * @return <code>true</code> if this prerequisite is not required
     *)
    function isOptional(): boolean; stdcall;

    (**
     * @return <code>true</code> if this prerequisite is fulfilled
     *)
    function matches(): boolean; stdcall;

    (**
     * @return the match rule as it specified in manifest
     *)
    function getMatch: String; stdcall;
  end;

  (**
   * Documentation reference.
   * @version $Id: Documentation.delphi,v 1.1 2004/11/30 18:45:20 ddimon Exp $
   *)
  IReference = interface(IRdInterface)
  ['{FB2EDEEA-B230-4D28-9D7F-65A904459E74}']
    (**
     * @return the reference as specified in manifest
     *)
    function getRef: String; stdcall;

    (**
     * @return text to be used when making link for this reference
     **)
    function getCaption: String; stdcall;

    (**
     * @return element, for which this documentation reference is provided
     *)
    function getDeclaringIdentity: IIdentity; stdcall;
  end;

  (**
   * Manifest info holder interface.
   *
   * @see PluginRegistry#readManifestInfo(URL)
   * @version $Id: PluginRegistry.java,v 1.6 2006/02/11 16:19:52 ddimon Exp $
   *)
  IManifestInfo = interface(IRdInterface)
  ['{4E940274-C562-49D8-AAD6-EB8392DDAF4B}']
     (**
       * @return plug-in or plug-in fragment identifier
       *)
      function getId: string; stdcall;
        
      (**
       * @return plug-in or plug-in fragment version identifier
       *)
      function getVersion: TVersion; stdcall;
        
      (**
       * @return plug-in or plug-in fragment vendor
       *)
      function getVendor: string; stdcall;
        
      (**
       * @return plug-in identifier this, fragment contributes to or
       *         <code>null</code> if this info is for plug-in manifest
       *)
      function getPluginId: string; stdcall;
      (**
       * @return plug-in version identifier, this fragment contributes to or
       *         <code>null</code> if this info is for plug-in manifest
       *)
      function getPluginVersion: TVersion; stdcall;
        
      (**
       * @return plug-in version matching rule or <code>null</code> if this
       *         info is for plug-in manifest
       *)
      function getMatchingRule: string; stdcall;
  end;

  (**
   * Root interface to get access to all meta-information about discovered
   * plug-ins. All objects accessible from the registry are immutable. You
   * can imagine registry as a read-only storage of full information about
   * discovered plug-ins. There is only one exception from this rule: internal
   * state of registry, plug-in descriptors and plug-in elements can be modified
   * indirectly by {@link #register(URL[]) registering} or
   * {@link #unregister(String[]) un-registering} plug-ins with this
   * registry. If your code is interested to be notified on all modifications
   * of plug-ins set, you can
   * {@link #registerListener(PluginRegistry.RegistryChangeListener) register}
   * an implementation of {@link PluginRegistry.RegistryChangeListener} with this
   * registry.
   * @version $Id: PluginRegistry.java,v 1.7 2005/03/13 14:20:24 ddimon Exp $
   *)
  IPluginRegistry = interface(IRdInterface)
  ['{6379348B-D0E2-4BB9-A3FA-DAA2CC969027}']
    procedure clearPlugins; stdcall;
    (**
     * Registers plug-ins and plug-in fragments in this registry. Note that
     * this method not makes plug-ins available for activation
     * by any {@link PluginManager} instance as it is not aware of any manager.
     * Using this method just makes plug-in meta-data available for reading from
     * this registry.
     * <p>
     * If more than one version of the same plug-in or plug-in fragment given,
     * the only latest version should be registered. If some plug-in or plug-in
     * fragment already registered it should be ignored by this method. Client
     * application have to un-register such plug-ins first before registering
     * their newest versions.
     * @param manifests array of manifest locations
     * @return map where keys are URL's and values are registered plug-ins
     *         or plug-in fragments, URL's for unprocessed manifests are
     *         not included
     * @see PluginManager#registerPlugins(Map)
     *)
    function register(manifests: IStrList): IStrIntfMap; stdcall;

    (**
     * Unregisters plug-ins and plug-in fragments with given ID's
     * (including depending plug-ins and plug-in fragments).
     * @param ids ID's of plug-ins and plug-in fragments to be
     *        unregistered
     * @return collection of UID's of actually unregistered plug-ins and plug-in
     *         fragments
     *)
    function unregister(ids: TStrings): IStrCollection; stdcall;

    (**
     * Returns descriptor of plug-in with given ID.
     * <br>
     * If plug-in descriptor with given ID can't be found or such plug-in
     * exists but is damaged this method have to throw an
     * {@link IllegalArgumentException}. In other words, this method
     * shouldn't return <code>null</code>.
     * @param pluginId plug-id ID
     * @return plug-in descriptor
     *)
    function getPluginDescriptor(pluginId: String): IPluginDescriptor; stdcall;
    
    (**
     * Returns collection of descriptors of all plug-ins that was successfully
     * populated by this registry.
     * @return collection of {@link PluginDescriptor} objects
     *)
    function getPluginDescriptors: IIntfCollection; stdcall;

    (**
     * Looks for extension point. This method have throw an
     * {@link IllegalArgumentException} if requested extension point
     * can't be found or is in invalid state.
     * @param pluginId plug-in ID
     * @param pointId extension point ID
     * @return plug-in extension point
     * @see ExtensionPoint#isValid()
     *)
//    function getExtensionPoint(pluginId, pointId: string): IExtensionPoint;
//        overload;

    (**
     * Looks for extension point.
     * @param uniqueId extension point unique ID
     * @return plug-in extension point
     * @see #getExtensionPoint(String, String)
     *)
//    function getExtensionPoint(uniqueId: String): IExtensionPoint; overload;

    (**
     * Checks if plug-in exists and is in valid state. If this method
     * returns <code>true</code>, the method
     * {@link #getPluginDescriptor(String)} should always return valid plug-in
     * descriptor.
     * @param pluginId plug-in ID
     * @return <code>true</code> if plug-in exists and valid
     *)
    function isPluginDescriptorAvailable(pluginId: string): Boolean; stdcall;

    (**
     * Checks if extension point exists and is in valid state. If this method
     * returns <code>true</code>, the method
     * {@link #getExtensionPoint(String, String)} should always return valid
     * extension point.
     * @param pluginId plug-in ID
     * @param pointId extension point ID
     * @return <code>true</code> if extension point exists and valid
     *)
//    function isExtensionPointAvailable(pluginId, pointId: String): boolean;
//        overload;

    (**
     * Checks if extension point exists and is in valid state.
     * @param uniqueId extension point unique ID
     * @return <code>true</code> if extension point exists and valid
     * @see #isExtensionPointAvailable(String, String)
     *)
//    function isExtensionPointAvailable(uniqueId: String): boolean; overload;

    (**
     * Returns collection of descriptors of all plug-in fragments that was
     * successfully populated by this registry.
     * @return collection of {@link PluginFragment} objects
     *)
    function getPluginFragments: IIntfCollection; stdcall;
    
    (**
     * Utility method that recursively collects all plug-ins that depends on
     * the given plug-in.
     * @param descr descriptor of plug-in to collect dependencies for
     * @return collection of {@link PluginDescriptor plug-in descriptors}
     *         that depend on given plug-in
     *)
    function getDependingPlugins(descr: IPluginDescriptor): IIntfCollection; stdcall;

    (**
     * Performs integrity check of all registered plug-ins and generates result
     * as a collection of standard report items.
     * @param pathResolver optional path resolver
     * @return integrity check report
     *)
//    function checkIntegrity(pathResolver: IPathResolver): IIntegrityCheckReport;
//        overload;

    (**
     * Performs integrity check of all registered plug-ins and generates result
     * as a collection of standard report items.
     * @param pathResolver optional path resolver
     * @param includeRegistrationReport if <code>true</code>, the plug-ins
     *                                  registration report will be included
     *                                  into resulting report
     * @return integrity check report
     *)
//    function checkIntegrity(pathResolver: IPathResolver; includeRegistrationReport:
//        boolean): IIntegrityCheckReport; overload;
    procedure configure(config: TExtendedProperties); stdcall;

    (**
     * @return plug-ins registration report for this registry
     *)
//    function getRegistrationReport: IIntegrityCheckReport;

    (**
     * Constructs unique identifier for some plug-in element from it's ID.
     * @param pluginId plug-in ID
     * @param elementId element ID
     * @return unique ID
     *)
    function makeUniqueId(pluginId, id: String): String; overload; stdcall;

    (**
     * Constructs unique identifier for plug-in with given ID.
     * @param pluginId plug-in ID
     * @param version plug-in version identifier
     * @return unique plug-in ID
     *)
    function makeUniqueId(pluginId: String; version: TVersion): String; stdcall; overload;

    (**
     * Extracts plug-in ID from some unique identifier.
     * @param uniqueId unique ID
     * @return plug-in ID
     *)
    function extractPluginId(uniqueId: String): String; stdcall;

    (**
     * Extracts plug-in element ID from some unique identifier.
     * @param uniqueId unique ID
     * @return element ID
     *)
    function extractId(uniqueId: String): String; stdcall;
    
    (**
     * Extracts plug-in version identifier from some unique identifier
     * (plug-in or plug-in fragment).
     * @param uniqueId unique ID
     * @return plug-in version identifier
     *)
    function extractVersion(uniqueId: String): TVersion; stdcall;
    (**
     * Looks for extension point.
     * @param uniqueId extension point unique ID
     * @return plug-in extension point
     * @see #getExtensionPoint(String, String)
     *)
    function getExtensionPoint(uniqueId: String): IExtensionPoint; overload; stdcall;
    (**
     * Looks for extension point. This method have throw an
     * {@link IllegalArgumentException} if requested extension point
     * can't be found or is in invalid state.
     * @param pluginId plug-in ID
     * @param pointId extension point ID
     * @return plug-in extension point
     * @see ExtensionPoint#isValid()
     *)
    function getExtensionPoint(pluginId, pointId: string): IExtensionPoint;
        overload; stdcall;
    (**
     * Checks if extension point exists and is in valid state.
     * @param uniqueId extension point unique ID
     * @return <code>true</code> if extension point exists and valid
     * @see #isExtensionPointAvailable(String, String)
     *)
    function isExtensionPointAvailable(uniqueId: String): boolean; overload; stdcall;
    (**
     * Checks if extension point exists and is in valid state. If this method
     * returns <code>true</code>, the method
     * {@link #getExtensionPoint(String, String)} should always return valid
     * extension point.
     * @param pluginId plug-in ID
     * @param pointId extension point ID
     * @return <code>true</code> if extension point exists and valid
     *)
    function isExtensionPointAvailable(pluginId, pointId: String): boolean;
        overload; stdcall;

    (**
     * Reads basic information from a plug-in of plug-in fragment manifest.
     * @param manifest manifest data URL
     * @return manifest info
     * @throws ManifestProcessingException if manifest data can't be read
     *)
    function readManifestInfo(url: string): IManifestInfo; stdcall;

    (**
     * Registers plug-in registry change event listener. If given listener has
     * been registered before, this method should throw an
     * {@link IllegalArgumentException}.
     * @param listener new registry change event listener
     *)
    procedure registerListener(listener: IRegistryChangeListener); stdcall;
    
    (**
     * Unregisters registry change event listener. If given listener hasn't been
     * registered before, this method should throw an
     * {@link IllegalArgumentException}.
     * @param listener registered listener
     *)
    procedure unregisterListener(listener: IRegistryChangeListener); stdcall;
  end;  

//==============================================================================
// PluginResistry
//==============================================================================

  (**
   * Registry changes data holder interface.
   * @version $Id: PluginRegistry.java,v 1.7 2005/03/13 14:20:24 ddimon Exp $
   *)
  IRegistryChangeData = interface(IRdInterface)
  ['{6B78C366-B82E-46DE-B0BA-85348C878E88}']
    (**
     * @return collection of ID's of newly added plug-ins
     *)
    function addedPlugins: IStrSet; stdcall;

    (**
     * @return collection of ID's of removed plug-ins
     *)
    function removedPlugins: IStrSet; stdcall;

    (**
     * @return collection of ID's of changed plug-ins
     *)
    function modifiedPlugins: IStrSet; stdcall;

    (**
     * @return collection of unique ID's of newly connected extensions
     *)
    function addedExtensions: IStrSet; overload; stdcall;

    (**
     * @param extensionPointUid unique ID of extension point to filter
     *                          result
     * @return collection of unique ID's of newly connected extensions
     *)
    function addedExtensions(extensionPointUid: String): IStrSet; overload;stdcall;

    (**
     * @return collection of unique ID's of disconnected extensions
     *)
    function removedExtensions: IStrSet; overload;stdcall;

    (**
     * @param extensionPointUid unique ID of extension point to filter
     *                          result
     * @return collection of unique ID's of disconnected extensions
     *)
    function removedExtensions(extensionPointUid: String): IStrSet; overload;stdcall;

    (**
     * @return collection of unique ID's of modified extensions
     *)
    function modifiedExtensions: IStrSet; overload;stdcall;

    (**
     * @param extensionPointUid unique ID of extension point to filter
     *                          result
     * @return collection of unique ID's of modified extensions
     *)
    function modifiedExtensions(extensionPointUid: String): IStrSet; overload; stdcall;
  end;

  (**
   * Plug-in registry changes callback interface.
   * @version $Id: PluginRegistry.java,v 1.7 2005/03/13 14:20:24 ddimon Exp $
   *)
  IRegistryChangeListener = interface(IRdInterface)
  ['{8EAC8585-10C6-41B1-B54E-F1E09F59A584}']
      (**
       * This method will be called by the framework when changes are made
       * on registry (via {@link PluginRegistry#register(URL[])} or
       * {@link PluginRegistry#unregister(String[])} methods).
       * @param data registry changes data
       *)
    procedure registryChanged(data: IRegistryChangeData); stdcall;
  end;

  (**
   * This interface abstracts an extension - particular functionality,
   * the plug-in contribute to the system
   * @version $Id: Extension.java,v 1.2 2005/03/07 10:27:57 ddimon Exp $
   *)
  IExtension = interface(IPluginElement)
  ['{085E4552-10E0-4253-925B-93BF20403CC3}']
    (**
     * Returns combination of plug-in ID and extension ID that is unique
     * within whole set of plug-ins, available for activation.
     * @return unique ID for this extension
     *)
    function getUniqueId: String; stdcall;

    (**
     * Returns collection of all top level parameters defined in this extension.
     * @return collection of {@link Extension.Parameter} objects
     *)
    function getParameters: IIntfCollection; overload; stdcall;

    (**
     * Returns top level parameter with given ID or <code>null</code> if no top
     * level parameters exist. If more than one top level parameters with given
     * ID found, the method should throw an {@link IllegalArgumentException}.
     * @param id ID of parameter to look for
     * @return top level parameter with given ID
     *)
    function getParameter(id: String): IParameter; stdcall;

    (**
     * @param id ID of parameter to look for
     * @return collection of all top level parameters with given ID
     *)
    function getParameters(id: String): IIntfCollection; overload; stdcall;

    (**
     * @return ID of plug-in, extended point belongs to
     *)
    function getExtendedPluginId: String; stdcall;
    
    (**
     * @return ID of extended point
     *)
    function getExtendedPointId: String; stdcall;
    
    (**
     * @return <code>true</code> if extension is considered to be valid
     *)
    function isValid: Boolean;  stdcall;
    function validate: IIntfCollection; stdcall;

    (**
     * This interface abstracts extension parameter according to extension
     * declaration in manifest.
     * @version $Id: Extension.java,v 1.2 2005/03/07 10:27:57 ddimon Exp $
     *)
  end;

  (**
   * This interface abstracts the extension point - a place where the
   * functionality of plug-in can be extended.
   * @version $Id: ExtensionPoint.java,v 1.1 2004/11/30 18:45:20 ddimon Exp $
   *)
  IExtensionPoint = interface(IPluginElement)
  ['{EF5C0138-5982-48B2-8575-4B236752A4EB}']
    (**
     * Returns combination of plug-in ID and extension point ID that is unique
     * within whole set of plug-ins, available for activation.
     * @return unique ID for this extension point
     *)
    function getUniqueId: String; stdcall;

    (**
     * @return multiplicity of this extension point
     *)
    function getMultiplicity: String; stdcall;

    (**
     * Returns collection of all top level parameter definitions declared
     * in this extension point and all it parents.
     * @return collection of {@link ExtensionPoint.ParameterDefinition} objects
     *)
    function getParameterDefinitions: IIntfCollection; stdcall;

    (**
     * @param id ID of parameter definition to look for
     * @return parameter definition with given ID
     *)
    function getParameterDefinition(id: String): IParameterDefinition; stdcall;

    (**
     * Returns a collection of all extensions that available for this point.
     * @return collection of {@link Extension} objects
     *)
    function getAvailableExtensions(): IIntfCollection; stdcall;
    
    (**
     * @param uniqueId unique ID of extension
     * @return extension that is available for this point
     *)
    function getAvailableExtension(uniqueId: string): IExtension; stdcall;
    
    (**
     * Checks if extension is available for this extension point. If this method
     * returns <code>true</code>, the method
     * {@link #getAvailableExtension(String)} should return valid extension for
     * the same UID.
     * @param uniqueId unique ID of extension
     * @return <code>true</code> if extension is available for this extension
     *         point
     *)
    function isExtensionAvailable(uniqueId: string): Boolean; stdcall;


    (**
     * Returns a collection of all extensions that was successfully "connected"
     * to this point.
     * @return collection of {@link Extension} objects
     *)
    function getConnectedExtensions: IIntfCollection; stdcall;

    (**
     * @param uniqueId unique ID of extension
     * @return extension that was successfully "connected" to this point
     *)
    function getConnectedExtension(uniqueId: String): IExtension; stdcall;
    
    (**
     * Checks if extension is in valid state and successfully "connected"
     * to this extension point. If this method returns <code>true</code>,
     * the method {@link #getConnectedExtension(String)} should return
     * valid extension for the same UID.
     * @param uniqueId unique ID of extension
     * @return <code>true</code> if extension was successfully "connected" to
     *         this extension point
     *)
    function isExtensionConnected(uniqueId: String): boolean; stdcall;
    
    (**
     * @return <code>true</code> if extension point is considered to be valid
     *)
    function isValid: boolean; stdcall;
    
    (**
     * @return parent extension point plug-in ID or <code>null</code>
     *)
    function getParentPluginId: String; stdcall;
    
    (**
     * @return parent extension point ID or <code>null</code>
     *)
    function getParentExtensionPointId: String; stdcall;
    
    (**
     * @param extensionPoint extension point
     * @return <code>true</code> if this point is successor of given extension
     *         point
     *)
    function isSuccessorOf(extensionPoint: IExtensionPoint): boolean; stdcall;
    
    (**
     * Looks for all available (valid) successors of this extension point.
     * The search should be done recursively including all descendants of this
     * extension point.
     * @return collection of {@link ExtensionPoint} objects
     *)
    function getDescendants: IIntfCollection; stdcall;
    function validate: IIntfCollection;   stdcall;

    (**
     * This interface abstracts parameter definition - a parameter
     * "type declaration".
     * @version $Id: ExtensionPoint.java,v 1.1 2004/11/30 18:45:20 ddimon Exp $
     *)
   end;

  IParameter = interface(IPluginElement)
  ['{2B066E38-5654-48C8-87F9-B8E2B7871895}']
    (**
     * @return parameter value as it is specified in manifest, if no value
     *         provided there, this method should return empty string
     *)
    function rawValue: String; stdcall;

    (**
     * Returns collection of all sub-parameters defined in this parameter.
     * @return collection of {@link Extension.Parameter} objects
     *)
    function getSubParameters: IIntfCollection; overload;stdcall;

    (**
     * Returns sub-parameter with given ID or <code>null</code> if no
     * sub-parameters exist. If more than one sub-parameters with given ID
     * found, the method should throw an {@link IllegalArgumentException}.
     * @param id ID of sub-parameter to look for
     * @return sub-parameter with given ID
     *)
    function getSubParameter(id: String): IParameter; stdcall;

    (**
     * @param id ID of sub-parameter to look for
     * @return collection of all sub-parameters with given ID
     *)
    function getSubParameters(id: String): IIntfCollection; overload; stdcall;

    (**
     * @return extension this parameter belongs to
     *)
    function getDeclaringExtension: IExtension;  stdcall;
        
    (**
     * Returns definition for this extension parameter.
     * May return <code>null</code> for "invalid" parameters.
     * @return parameter definition or <code>null</code>, if this parameter
     *         is "invalid"
     *)
    function getDefinition: IParameterDefinition;  stdcall;

    (**
     * @return parameter, of which this one is child or <code>null</code> if
     *         this is top level parameter
     *)
    function getSuperParameter: IParameter; stdcall;
        
    (**
     * Returns "typed" value of parameter. If this parameter is invalid or
     * is not of type
     * {@link ExtensionPoint.ParameterDefinition#TYPE_STRING}, this method
     * should throw an {@link UnsupportedOperationException}.
     * @return value as String object
     *)
    function valueAsString: String; stdcall;
        
    (**
     * Returns "typed" value of parameter. If this parameter is invalid or
     * is not of type
     * {@link ExtensionPoint.ParameterDefinition#TYPE_BOOLEAN}, this method
     * should throw an {@link UnsupportedOperationException}.
     * @return value as Boolean object
     *)
    function valueAsBoolean: Boolean; stdcall;
        
    (**
     * Returns "typed" value of parameter. If this parameter is invalid or
     * is not of type
     * {@link ExtensionPoint.ParameterDefinition#TYPE_NUMBER}, this method
     * should throw an {@link UnsupportedOperationException}.
     * @return value as Number object
     *)
     
    //Number valueAsNumber();
    function valueAsNumber: Integer; stdcall;

    (**
     * Returns "typed" value of parameter. If this parameter is invalid or
     * is not of type {@link ExtensionPoint.ParameterDefinition#TYPE_DATE},
     * {@link ExtensionPoint.ParameterDefinition#TYPE_TIME}
     * or {@link ExtensionPoint.ParameterDefinition#TYPE_DATETIME},
     * this method should throw an {@link UnsupportedOperationException}.
     * @return value as Date object
     *)
    function valueAsDate: TDateTime;  stdcall;
        
    (**
     * Returns "typed" value of parameter. If this parameter is invalid or
     * is not of type
     * {@link ExtensionPoint.ParameterDefinition#TYPE_PLUGIN_ID}, this
     * method should throw an {@link UnsupportedOperationException}.
     * @return value as PluginDescriptor object
     *)
    function valueAsPluginDescriptor: IPluginDescriptor;  stdcall;
        
    (**
     * Returns "typed" value of parameter. If this parameter is invalid or
     * is not of type
     * {@link ExtensionPoint.ParameterDefinition#TYPE_EXTENSION_POINT_ID},
     * this method should throw an {@link UnsupportedOperationException}.
     * @return value as ExtensionPoint object
     *)
    function valueAsExtensionPoint: IExtensionPoint; stdcall;
        
    (**
     * Returns "typed" value of parameter. If this parameter is invalid or
     * is not of type
     * {@link ExtensionPoint.ParameterDefinition#TYPE_EXTENSION_ID}, this
     * method should throw an {@link UnsupportedOperationException}.
     * @return value as Extension object
     *)
    function valueAsExtension: IExtension; stdcall;

    (**
     * Returns "typed" value of parameter. If this parameter is invalid or
     * is not of type
     * {@link ExtensionPoint.ParameterDefinition#TYPE_RESOURCE}, this
     * method should throw an {@link UnsupportedOperationException}.
     * @return value as absolute or relative URL as specified in manifest
     *)
    function valueAsUrl: string; overload; stdcall;

    (**
     * Returns "typed" value of parameter. If this parameter is invalid or
     * is not of type
     * {@link ExtensionPoint.ParameterDefinition#TYPE_RESOURCE}, this
     * method should throw an {@link UnsupportedOperationException}.
     * @param pathResolver path resolver to make URL absolute
     * @return value as absolute URL
     *)
    function valueAsUrl(pathResolver: IPathResolver): string; overload; stdcall;
  end;

  IParameterDefinition = interface(IPluginElement)
  ['{51BC7DB6-DD55-4A7F-B35C-57054E502A71}']
    (**
     * @return multiplicity of parameter, that can be defined according
     *         to this definition
     *)
    function getMultiplicity: String; stdcall;

    (**
     * @return value type of parameter, that can be defined according
     *         to this definition
     *)
    function getType: String; stdcall;
        
    (**
     * @return custom data for additional customization of some types
     *)
    function getCustomData: String; stdcall;

    (**
     * Returns collection of all parameter sub-definitions declared
     * in this parameter definition.
     * @return collection of {@link ExtensionPoint.ParameterDefinition}
     *         objects
     *)
    function getSubDefinitions: IIntfCollection; stdcall;

    (**
     * @param id ID of parameter sub-definition to look for
     * @return parameter sub-definition with given ID
     *)
    function getSubDefinition(id: String): IParameterDefinition; stdcall;

    (**
     * @return extension point, this definition belongs to
     *)
    function getDeclaringExtensionPoint: IExtensionPoint; stdcall;
        
    (**
     * @return parameter definition, of which this one is child or
     *         <code>null</code> if this is top level parameter definition
     *)
    function getSuperDefinition: IParameterDefinition; stdcall;
  end;

implementation

end.
